﻿#include "DrillingrigMediator.h"
#include <QJsonObject>
#include <QJsonArray>
#include "EquipmentAction.h"
#include "MediatorEventDefine.h"
#include "DrillingrigEvent.h"
#include "ModbusClientProxy.h"

DrillingrigMediator::DrillingrigMediator(QObject* parent)
	: QObject(parent)
{
}

DrillingrigMediator::~DrillingrigMediator()
{
}

void DrillingrigMediator::registerAction(EquipmentAction* action, QStringView const name) {
	auto iter = m_equipmentActions.find(name.toString());
	if (iter == std::cend(m_equipmentActions)) {
		m_equipmentActions[name.toString()] = action;
		action->setMediator(this);
	}
}

void DrillingrigMediator::unRegisterAction(QStringView const name) {
	auto it = m_equipmentActions.find(name.toString());
	if (it != std::cend(m_equipmentActions)) {
		std::invoke(&EquipmentAction::setMediator, it->second, nullptr);
		m_equipmentActions.erase(it);
	}
}

void DrillingrigMediator::push(QJsonObject const& obj, QStringView const who) {
	for (auto it = std::cbegin(m_equipmentActions); it != std::cend(m_equipmentActions); it++){
		if (it->first == who) {
			continue;
		}
		std::invoke(&EquipmentAction::update, it->second, std::cref(obj));
	}
}

void DrillingrigMediator::push(QJsonObject const& obj, QStringView const who, QStringView const to) {
	if (to.isEmpty()) {
		return push(obj, who);
	}
	auto iter = m_equipmentActions.find(to.toString());
	if (iter != std::cend(m_equipmentActions)) {
		std::invoke(&EquipmentAction::update, iter->second, std::move(obj));
	}
}

void DrillingrigMediator::reportLog(QStringView log, int level /*= 0*/) {
	auto it = m_equipmentActions.find(DrillingrigEvent::Identity.toString());
	if (it != std::cend(m_equipmentActions)) {
		QJsonObject obj;
		obj[ME_MSG_KEY] = ME_REPORTLOG.toString();
		obj["msg"] = log.toString();
		obj["level"] = level;
		std::invoke(&EquipmentAction::update, it->second, std::cref(obj));
	}
	else {
		qDebug() << QStringView(u"查找交互事件(event)对象失败");
	}
}

void DrillingrigMediator::connectStateChanged(int state){
	for (auto it = std::cbegin(m_equipmentActions); it != std::cend(m_equipmentActions); it = std::next(it)) {
		if (it->first == ModbusClientProxy::Identity) {
			continue;
		}
		QJsonObject obj;
		obj[ME_MSG_KEY] = ME_CONNECTSTATE.toString();
		obj["state"] = state;
		std::invoke(&EquipmentAction::update, it->second, std::cref(obj));
	}
}

QVariant DrillingrigMediator::request(QJsonObject const& obj, QStringView const requester, QStringView const to) {
	auto it = m_equipmentActions.find(to.toString());
	if (it == std::cend(m_equipmentActions)) {
		return QVariant();
	}
	auto result = std::invoke(&EquipmentAction::request, it->second, std::cref(obj), requester);
	return result;
}

void DrillingrigMediator::setCamera(QStringList const& cameras) {
	auto it = m_equipmentActions.find(DrillingrigEvent::Identity.toString());
	if (it != std::cend(m_equipmentActions)) {
		QJsonObject obj;
		QJsonArray camerasArr;
		std::transform(std::cbegin(cameras), std::cend(cameras), std::back_inserter(camerasArr), [](QString const& str) { return str; });
		obj[ME_MSG_KEY] = ME_UPDATECAMERA.toString();
		obj["msg"] = camerasArr;
		std::invoke(&EquipmentAction::update, it->second, std::cref(obj));		
	}
	else {
		qDebug() << QStringView(u"查找交互事件(event)对象失败");
	}
}
